<template>
  <t-card :bordered="false">
    <!-- 自定义搜索 -->
    <custom-search ref="customSearchRef" v-slot="{ params }" @submit="handleInitTable">
      <t-col :span="3">
        <t-form-item label="任务名称" prop="name">
          <t-input v-model="params.name" placeholder="请输入任务名称" clearable />
        </t-form-item>
      </t-col>
      <t-col :span="3">
        <t-form-item label="任务状态" prop="status">
          <t-select v-model="params.status" placeholder="请选择任务状态" clearable filterable
            :options="dictionaryStore.get('infra_job_status')" />
        </t-form-item>
      </t-col>
      <t-col :span="3">
        <t-form-item label="处理器的名字" prop="handlerName">
          <t-input v-model="params.handlerName" placeholder="请输入处理器的名字" clearable />
        </t-form-item>
      </t-col>
    </custom-search>
    <!-- 自定义表格 -->
    <custom-table ref="customTableRef" row-key="id" :columns="columns" :api="infraJobCRUD.page"
      column-controller-key="SystemJobList">
      <template #topContent>
        <div style="margin-bottom: var(--td-comp-margin-xxl)">
          <t-button v-permission="['infra:job:create']" @click="handleOpenDialog('create', { status: 0 })">
            新建任务
          </t-button>
          <t-button v-permission="['infra:job:query']" @click="handleJobLog()">
            执行日志
          </t-button>
        </div>
      </template>
      <template #status="{ row }">
        <t-tag variant="light" :theme="getTimelineDotColor(row.status)">{{
          dictionaryStore.analysis('infra_job_status', row.status)
        }}</t-tag>
      </template>
      <template #operation="{ row }">
        <t-space break-line>
          <t-link v-permission="['infra:job:query']" theme="primary" @click="handleOpenDialog('read', { id: row.id })">
            详情
          </t-link>
          <t-link v-permission="['infra:job:update']" theme="primary"
            @click="handleOpenDialog('update', { id: row.id })">
            编辑
          </t-link>
          <t-popconfirm :content="`确认要${row.status === 2 ? '开启' : '关闭'}该项定时任务吗？`" @confirm="handleChangeStatus(row)">
            <t-link v-permission="['infra:job:update']" theme="primary"> {{ row.status === 2 ? '开启' : '暂停' }} </t-link>
          </t-popconfirm>
          <t-popconfirm content="确认要删除该项吗？" @confirm="handleDelete({ id: row.id })">
            <t-link v-permission="['infra:job:delete']" theme="danger"> 删除 </t-link>
          </t-popconfirm>
          <t-dropdown :min-column-width="88" @click="(data) => clickHandler(data, row)">
            <t-link theme="primary">更多</t-link>
            <template #dropdown>
              <t-dropdown-menu>
                <t-dropdown-item command="handleRun" v-permission="['infra:job:trigger']">
                  执行一次
                </t-dropdown-item>
                <t-dropdown-item command="openDetail" v-permission="['infra:job:query']">
                  任务详细
                </t-dropdown-item>
                <t-dropdown-item command="handleJobLog" v-permission="['infra:job:query']">
                  调度日志
                </t-dropdown-item>

              </t-dropdown-menu>
            </template>
          </t-dropdown>
        </t-space>
      </template>
    </custom-table>
    <!-- 自定义对话框 -->
    <custom-dialog ref="customDialogRef" v-slot="{ formData, readonly, mode }" :api-map="infraJobCRUD" header="*任务"
      @request-success="handleDialogRequestSuccess">
      <t-form-item label="任务名称" name="name" :rules="[{ required: true, message: '请输入任务名称' }]">
        <t-input v-model:value="formData.name" placeholder="请输入任务名称" clearable :readonly="readonly" />
      </t-form-item>
      <t-form-item label="处理器的名字" name="handlerName" :rules="[{ required: true, message: '请输入处理器的名字' }]">
        <t-input v-model:value="formData.handlerName" placeholder="请输入处理器的名字" clearable :readonly="readonly" />
      </t-form-item>
      <t-form-item label="处理器的参数" name="handlerParam" :rules="[{ required: false, message: '请输入处理器的参数' }]">
        <t-input v-model:value="formData.handlerParam" placeholder="请输入处理器的参数" clearable :readonly="readonly" />
      </t-form-item>
      <t-form-item label="CRON 表达式" name="cronExpression" :rules="[{ required: true, message: '请输入CRON 表达式' }]">
        <!-- <t-input v-model:value="formData.cronExpression" placeholder="请输入CRON 表达式" clearable :readonly="readonly" /> -->
        <crontab v-model="formData.cronExpression" />
      </t-form-item>
      <t-form-item label="重试次数" name="retryCount" :rules="[{ required: true, message: '请输入重试次数' }]">
        <t-input v-model:value="formData.retryCount" placeholder="请输入重试次数。设置为 0 时，不进行重试" clearable
          :readonly="readonly" />
      </t-form-item>
      <t-form-item label="重试间隔" name="retryInterval" :rules="[{ required: true, message: '请输入重试间隔' }]">
        <t-input v-model:value="formData.retryInterval" placeholder="请输入重试间隔，单位：毫秒。设置为 0 时，无需间隔" clearable
          :readonly="readonly" />
      </t-form-item>
      <t-form-item label="监控超时时间" name="monitorTimeout" :rules="[{ required: false, message: '请输入监控超时时间' }]">
        <t-input v-model:value="formData.monitorTimeout" placeholder="请输入监控超时时间，单位：毫秒" clearable :readonly="readonly" />
      </t-form-item>
    </custom-dialog>
    <!-- 表单弹窗：查看 -->
    <JobDetail ref="detailRef" />
  </t-card>
</template>
<script lang="ts">
export default {
  name: 'SystemJob',
};
</script>

<script lang="ts" setup>
import dayjs from 'dayjs';
import { DialogPlugin, MessagePlugin, TableCol } from 'tdesign-vue-next';
import { onMounted, ref, useTemplateRef } from 'vue';
import { useRouter } from 'vue-router';

import { infraJobCRUD, infraJobUpdateStatus, runJob } from '@/api/system/job';
import CustomDialog from '@/components/custom/dialog/index.vue';
import CustomSearch from '@/components/custom/search/index.vue';
import CustomTable from '@/components/custom/table/index.vue';
import Crontab from './components/Crontab.vue';
import JobDetail from './components/JobDetail.vue';
import { useDictionaryStore } from '@/store';

// 字典仓库
const dictionaryStore = useDictionaryStore();
// 自定义搜索ref
const customSearchRef = useTemplateRef('customSearchRef');
// 自定义表格ref
const customTableRef = useTemplateRef('customTableRef');

const router = useRouter();

// columns
const columns: TableCol[] = [
  { colKey: 'id', title: '任务编号' },
  { colKey: 'name', title: '任务名称' },
  { colKey: 'status', title: '任务状态' },
  { colKey: 'handlerName', title: '处理器的名字' },
  { colKey: 'handlerParam', title: '处理器的参数' },
  { colKey: 'cronExpression', title: 'CRON 表达式' },
  { colKey: 'operation', title: '操作', width: 240 },
];
// 处理初始化表格
const handleInitTable = () => {
  const params = { ...customSearchRef.value.params };
  customTableRef.value.initTable(params);
};
// 处理刷新表格
const handleRefreshTable = () => {
  customTableRef.value.refreshTable();
};
onMounted(() => {
  handleInitTable();
});
// 自定义对话框ref
const customDialogRef = useTemplateRef('customDialogRef');
// 处理打开对话框
const handleOpenDialog = (mode: 'create' | 'read' | 'update', params: Record<string, any>) => {
  customDialogRef.value.open(mode, params);
};
// 处理对话框请求成功
const handleDialogRequestSuccess = (result: Record<string, any>) => {
  if (result.mode === 'create') handleInitTable();
  if (result.mode === 'update') handleRefreshTable();
};
// 处理删除
const handleDelete = (params: Record<string, any>) => {
  infraJobCRUD
    .delete(params)
    .then(() => {
      MessagePlugin.success('删除成功');
      handleRefreshTable();
    })
    .catch(({ message }) => {
      MessagePlugin.error(message);
    });
};
// 处理改变状态
const handleChangeStatus = (row: Record<string, any>) => {
  row.loading = true;
  const status = row.status === 2 ? 1 : 2
  const text = row.status === 2 ? '开启' : '关闭'
  const params = {
    id: row.id,
    status
  };
  infraJobUpdateStatus(params)
    .then(() => {
      MessagePlugin.success(text + '成功');
      handleRefreshTable();
    })
    .catch(({ message }) => {
      MessagePlugin.error(message);
    })
    .finally(() => {
      row.loading = false;
    });
};
const getTimelineDotColor = (result: number): 'default' | 'primary' | 'success' | 'danger' | 'warning' => {
  const map: ('primary' | 'success' | 'danger')[] = [
    'primary', 'success', 'danger'
  ]
  return result in map ? map[result] : 'default'
}
// 更多
const clickHandler = (data: any, row: any) => {
  const { command } = data
  switch (command) {
    case 'handleRun':
      handleRun(row)
      break
    case 'openDetail':
      openDetail(row.id)
      break
    case 'handleJobLog':
      handleJobLog(row?.id)
      break
    default:
      break
  }

}
/** 执行一次 */
const handleRun = (row: any) => {
  try {
    // 二次确认
    const confirmDia = DialogPlugin({
      // header: '确认生成产品订单',
      body: '确认要立即执行一次' + row.name + '?',
      confirmBtn: '确定',
      cancelBtn: '取消',
      onConfirm: async () => {
        // 提交执行
        await runJob(row.id)
        MessagePlugin.success('执行成功')
        confirmDia.hide()
        // 刷新列表
        await handleRefreshTable()
      },
      onClose: () => {
        // 用户点击"取消"或关闭弹窗时的操作
        confirmDia.hide()
      },
    });
  } catch { }
}
/** 查看操作 */
const detailRef = ref()
const openDetail = (id: number) => {
  detailRef.value.open(id)
}

/** 跳转执行日志 */
const handleJobLog = (id?: number) => {
  if (id && id > 0) {
    router.push('/system/job-log?id=' + id)
  } else {
    router.push('/system/job-log')
  }
}
</script>
